package com.service.lotterySystem.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.service.config.utils.*;
import com.service.lotterySystem.controller.OperateUserController;
import com.service.lotterySystem.dao.OperateInfoDao;
import com.service.lotterySystem.dto.LoginUserDto;
import com.service.lotterySystem.dto.OperateUserInfoDto;
import com.service.lotterySystem.entity.OperateInfo;
import com.service.lotterySystem.entity.OperateUserInfo;
import com.service.lotterySystem.service.FeginMstscUnique;
import com.service.lotterySystem.service.OperateUserService;
import com.service.lotterySystem.util.QRCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author ：hjl
 * @date ：Created in 2022/01/10 15:50
 * @description：管理人员表(ManageInfo)表服务实现类
 */
@Service("manageInfoService")
@Slf4j
public class OperateUserServiceImpl implements OperateUserService {
    @Resource
    private OperateInfoDao operateUserDao;

    @Resource
    private RedisUtil redisUtil;
    @Resource
    OperateUserController operateUserController;
    @Resource
    FeginMstscUnique feginMstscUnique;

    @Value("${spring.fileSeverDomain}")
    private String fileSeverDomain;
    @Value("${spring.imageUrl}")
    private String imageUrl;
    @Value("${spring.nginxUrl}")
    private String nginxUrl;
    // 二维码链接地址
    private static final String URL = "https://test.cloudcampusapps.top/materialCenter/uploadForm?oId=";
    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public OperateInfo queryById(String id) {
        OperateInfo operateInfo = this.operateUserDao.queryById(id);
        return ModelMapperUtil.strictMap(operateInfo, OperateInfo.class);
    }

    /**
     * 新增数据
     *
     * @param manageInfo 实例对象
     * @return 实例对象
     */
    @Override
    public OperateInfo insert(OperateInfo manageInfo) {
        OperateInfo operateInfo = ModelMapperUtil.strictMap(manageInfo, OperateInfo.class);
        this.operateUserDao.insert(operateInfo);
        return manageInfo;
    }

    /**
     * 修改数据
     *
     * @param manageInfo 实例对象
     * @return 实例对象
     */
    @Override
    public OperateInfo update(OperateInfo manageInfo) {
        OperateInfo operateInfo = ModelMapperUtil.strictMap(manageInfo, OperateInfo.class);
        this.operateUserDao.update(operateInfo);
        return manageInfo;
    }

    /**
     * 用户登录获取token
     * @param loginUserDto
     * @return
     * @throws Exception
     */
    @Override
    public HashMap getToken(LoginUserDto loginUserDto) throws Exception {
        HashMap map = new HashMap();
        OperateInfo operateInfo = operateUserDao.queryUserInfo(loginUserDto.getAccount(), loginUserDto.getPassword());
        if (operateInfo == null) {
            return (HashMap) Collections.EMPTY_MAP;
        }
        return getHashMap(loginUserDto, map, operateInfo);

    }

    @Override
    public OperateInfo register(OperateUserInfoDto userInfoDto, String realIp) {
        return getUserInfo(userInfoDto,realIp);
    }

    /**
     * 根据姓名查询新增用户
     * @param userId
     * @param name
     * @return
     */
    @Override
    public Map<String, Object> fineOperateUser(Integer page,Integer pageSize,String userId,String name,String region) {
        Map<String,Object> map = new HashMap<>(16);
        if (pageSize == null) {
            PageHelper.startPage(page,10,"add_time DESC");
        }else {
            PageHelper.startPage(page,pageSize,"add_time DESC");
        }
        List<OperateUserInfo> operateUserInfoList = operateUserDao.queryUserByNameLike(userId,region,name);
        List<OperateUserInfoDto> operateUserInfoDtoList = ModelMapperUtil.strictMapList(operateUserInfoList, OperateUserInfoDto.class);
        PageInfo<OperateUserInfoDto> pageInfo = new PageInfo<OperateUserInfoDto>(operateUserInfoDtoList);
        map.put("programmes",pageInfo.getList());
        map.put("pageSize",pageSize);
        map.put("pageIndex",page);
        map.put("totalRecords",pageInfo.getTotal());
        map.put("totalPages",pageInfo.getPages());
        return map;
    }

    @Override
    public Result addUrlScheme(String userId) {
        try {
            String encode = QRCodeUtil.encode(URL + userId, "", imageUrl+"/"+nginxUrl, false);
            String url = fileSeverDomain.concat("/"+nginxUrl+"/").concat(encode);
            OperateInfo operateInfo = new OperateInfo();
            operateInfo.setId(userId);
            operateInfo.setUrlScheme(url);
            operateUserDao.update(operateInfo);
            return Result.ok().setData(url);
        } catch (Exception e) {
            log.error("生成二维码错误："+e.getMessage());
        }
        return Result.failure("请重试");
    }

    /**
     * 根据强制登录标识符获取token
     * 强制标识符不存在且没有用户登录则直接返回token
     * 用户已登陆则直接返回用户重复登录码
     * @param loginUserDto
     * @param map
     * @param operateInfo
     * @return
     * @throws Exception
     */
    private HashMap getHashMap(LoginUserDto loginUserDto, HashMap map, OperateInfo operateInfo) throws Exception {
        OperateUserInfoDto userDto = ModelMapperUtil.strictMap(operateInfo, OperateUserInfoDto.class);
        userDto.setLoginTime(new Date()); //登录时间
        String token = "";
        Boolean isLogin = loginUserDto.getIsLogin();
        Set<String> strings = redisUtil.redisLike(operateInfo.getId());
        if (isLogin != null) {
            if (isLogin) { // 强制登录标识符
                token = UserTokenManager.generateToken(operateInfo.getId());
                operateUserController.clearCache(strings, redisUtil);
                HashMap map1 = setUserInfo(map, operateInfo, userDto, token);
                return map1;
            }
        }
        if (strings.size() >= 1) {
            map.put("errorCode","用户重复登陆");
            return map ;
        }else {
            token = UserTokenManager.generateToken(operateInfo.getId());
            HashMap map1 = setUserInfo(map, operateInfo, userDto, token); //更新用户信息
            return map1;
        }
    }

    /**
     * 更新用户信息并返回token
     * @param map
     * @param operateInfo
     * @param userDto
     * @param token
     * @return
     * @throws Exception
     */
    private HashMap setUserInfo(HashMap map, OperateInfo operateInfo, OperateUserInfoDto userDto, String token) throws Exception {
        OperateInfo operateInfo2 = ModelMapperUtil.strictMap(operateInfo, OperateInfo.class);
        operateUserDao.update(operateInfo2);
        redisUtil.setValue(token+operateInfo.getId(), JsonXMLUtils.obj2json(userDto)); // 存入缓存
        map.put("Token",token);
        map.put("type",operateInfo2.getRoleType());
        return map;
    }


    /**
     *  新增用户
     * @param userInfoDto
     * @param realIp
     * @return
     */
    private OperateInfo getUserInfo(OperateUserInfoDto userInfoDto, String realIp) {
        OperateInfo userInfo = ModelMapperUtil.strictMap(userInfoDto, OperateInfo.class);
        OperateInfo userInfo1 = operateUserDao.queryUserByName(userInfo.getOperateName());
        if (userInfo1 != null) {
            return null;
        }
        Result result = feginMstscUnique.addApiAccount();
        if (result.getCode() == 200) {
            userInfo.setId(result.getData().toString());
        }else {
            userInfo.setId(IdUtil.getStringId());
        }
        userInfo.setAddTime(new Date());
        userInfo.setLoginTime(new Date());
        operateUserDao.insert(userInfo);
        return userInfo;
    }
}
